﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Reflection;

namespace Less2DB.CodeGenerator
{
    internal partial class FNewProject : Form
    {
        class ProjectTreeNode : TreeNode
        {
            private Type projectListType;

            public Type ProjectListType
            {
                get { return projectListType; }
                set { projectListType = value; }
            }
        }

        public class ProjectListViewItem : ListViewItem
        {
            public ProjectListViewItem(string projectName)
            {
                this.projectName = projectName;
            }

            private string projectName;

            public string ProjectName
            {
                get { return projectName; }
            }

            private string description;

            public string Description
            {
                get { return description; }
                set { description = value; }
            }
        }

        /// <summary>
        /// 初始化新建项目窗口。
        /// </summary>
        public FNewProject()
        {
            InitializeComponent();
            FormInterfaceFactory.FormUI.Render(this, true);
            pnlTextInput.Bounds = new Rectangle(0, pnlTextInput.Top, ClientRectangle.Width, pnlTextInput.Height);
            pnlDefaultBackground.BackColor = FormInterfaceFactory.FormUI.BackColorTextboxPanel;
        }

        /// <summary>
        /// 重写窗口加载后的处理程序。
        /// </summary>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            ProjectItemsLoad();
            treeView.ExpandAll();
        }

        /// <summary>
        /// 浏览项目位置按钮的单击事件处理程序。
        /// </summary>
        private void btnBrowse_Click(object sender, EventArgs e)
        {
            if (fbDlgLocation.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                cmbProjectLocation.Text = fbDlgLocation.SelectedPath;
            }
        }

        /// <summary>
        /// 加载项目列表。
        /// </summary>
        private void ProjectItemsLoad()
        {
            using (Stream stream = Resources.GetProjectItems())
            {
                XmlDocument xmlDoc = new XmlDocument();

                xmlDoc.Load(stream);

                ProjectItemsCycleLoad(xmlDoc.SelectSingleNode("/ProjectItems"));
            }
        }

        /// <summary>
        /// 从 XmlNode 类型的对象中读取项目信息并添加到 TreeView 中。
        /// </summary>
        /// <param name="xmlNode">一个 XmlNode 类型的对象。</param>
        private void ProjectItemsCycleLoad(XmlNode xmlNode)
        {
            treeView.Nodes.Clear();
            ProjectItemsCycleLoad(xmlNode, null);
        }

        /// <summary>
        /// 从 XmlNode 类型的对象中读取项目信息并添加到 TreeView 中。
        /// </summary>
        /// <param name="xmlNode">一个 XmlNode 类型的对象。</param>
        /// <param name="treeNode">一个 TreeNode 类型的对象。</param>
        private void ProjectItemsCycleLoad(XmlNode xmlNode, TreeNode treeNode)
        {
            if (xmlNode.ChildNodes.Count > 0)
            {
                foreach (XmlNode childXmlNode in xmlNode.SelectNodes("Project"))
                {
                    var childTreeNode = ConvertXmlNodeToTreeNode(childXmlNode);

                    if (treeNode != null)
                    {
                        treeNode.Nodes.Add(childTreeNode);
                    }
                    else
                    {
                        treeView.Nodes.Add(childTreeNode);
                    }

                    ProjectItemsCycleLoad(childXmlNode, childTreeNode);
                }
            }
        }

        /// <summary>
        /// 将 XmlNode 类型的对象转换为 TreeNode 类型的对象。
        /// </summary>
        /// <param name="xmlNode">一个 XmlNode 类型的对象。</param>
        /// <returns>返回转换后的 TreeNode 类型的对象。</returns>
        private TreeNode ConvertXmlNodeToTreeNode(XmlNode xmlNode)
        {
            var treeNode = new ProjectTreeNode()
            {
                Text = xmlNode.SelectSingleNode("Name").InnerText
            };

            if (xmlNode.SelectSingleNode("Type") != null)
            {
                treeNode.ProjectListType = Type.GetType(xmlNode.SelectSingleNode("Type").InnerText);
            }

            return treeNode;
        }

        private void treeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Node is ProjectTreeNode)
            {
                var type = (e.Node as ProjectTreeNode).ProjectListType;

                listView.Items.Clear();

                if (type != null)
                {
                    var list = type.GetConstructor(new Type[0]).Invoke(null);

                    if (list is ProjectListTypes.ProjectList)
                    {
                        listView.Items.AddRange((list as ProjectListTypes.ProjectList).GetItems());
                    }
                }
            }
        }

        private void listView_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listView.SelectedItems.Count > 0)
            {
                if (listView.SelectedItems[0] is ProjectListViewItem)
                {
                    var listViewItem = listView.SelectedItems[0] as ProjectListViewItem;

                    txtProjectName.Text = listViewItem.ProjectName + "1";
                }
                else
                {
                    txtProjectName.Text = string.Empty;
                }

                if (cmbProjectLocation.Text == string.Empty)
                {
                    cmbProjectLocation.Text = Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments);
                }

                lblDescription.Text = (listView.SelectedItems[0] as ProjectListViewItem).Description;
            }
        }
    }
}
